package com.cxso.example.sdk.http.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * 签名工具类
 */
public class SignUtils {

    /**
     * AES加密
     */
    public static String aesEncrypt(String content, String clientSecret) throws Exception {
        byte[] key = clientSecret.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] combined = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(combined);
    }

    /**
     * AES解密
     */
    public static String aesDecrypt(String encryptContent, String clientSecret) throws Exception {
        byte[] key = clientSecret.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptContent);
        byte[] original = cipher.doFinal(encryptedBytes);
        return new String(original, StandardCharsets.UTF_8);
    }

    /**
     * 数据签名
     *
     * @param encryptContent 加密后的请求数据
     * @param timestamp      时间戳
     * @param privateKeyStr  私钥字符串（Base64 编码）
     * @return 签名
     */
    public static String signBody(String encryptContent, long timestamp, String privateKeyStr) throws Exception {
        // 签名内容
        String message = encryptContent + "#" + timestamp;
        // MD5摘要计算
        byte[] hash = md5(message).getBytes(StandardCharsets.UTF_8);

        // 加载私钥
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        // 使用 SHA256withRSA 签名算法
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(hash);
        // 生成签名
        byte[] signBytes = signature.sign();
        return Base64.getEncoder().encodeToString(signBytes);
    }

    /**
     * 计算MD5值
     *
     * @param data 数据
     * @return MD5摘要值
     */
    public static String md5(String data) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] hash = md.digest(data.getBytes(StandardCharsets.UTF_8));
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}
